package com.example.fashionshoes.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.fashionshoes.constant.JwtConst;
import com.example.fashionshoes.exception.BusinessException;
import com.example.fashionshoes.mapper.OrderMapper;
import com.example.fashionshoes.pojo.po.*;
import com.example.fashionshoes.pojo.vo.OrderDetailVo;
import com.example.fashionshoes.pojo.vo.OrderVo;
import com.example.fashionshoes.pojo.vo.ToPayVo;
import com.example.fashionshoes.service.*;
import com.example.fashionshoes.service.coupon.CouponContext;
import com.example.fashionshoes.service.coupon.CouponStrategy;
import com.example.fashionshoes.service.coupon.DiscountCoupon;
import com.example.fashionshoes.service.coupon.FullMinusCoupon;
import com.example.fashionshoes.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private CartService cartService;
    @Resource
    private AddressBookService addressBookService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private CouponService couponService;
    @Resource
    private UserCouponService userCouponService;

    /**
     * 生成订单-结算页
     *
     * @return 地址簿和商品
     */
    @Override
    public ToPayVo getCheckOutInfo(Integer userId) throws BusinessException {
        BigDecimal allPrice = new BigDecimal(0);
        List<ShoppingCart> shoppingCartList = cartService.lambdaQuery().eq(ShoppingCart::getUserId, userId).eq(ShoppingCart::getSelected, 1).list();
        BigDecimal discountPrice = new BigDecimal(0);
        boolean flag = true;
        boolean useCoupon = false;
        for (ShoppingCart shoppingCart : shoppingCartList) {
            allPrice = allPrice.add(shoppingCart.getPrice().multiply(BigDecimal.valueOf(shoppingCart.getCount())));
            if (shoppingCart.getUserCouponId() != null) {
                useCoupon = true;
                UserCoupon userCoupon = userCouponService.getById(shoppingCart.getUserCouponId());
                Coupon coupon = couponService.getById(userCoupon.getCouponId());
                CouponStrategy couponStrategy;
                CouponContext couponContext = new CouponContext();
                //策略模式实现
                //TODO 未考虑券的叠加
                if (coupon.getDiscount() != null) {
                    //折扣券
                    couponStrategy = new DiscountCoupon();
                    couponContext.setCouponStrategy(couponStrategy);
                } else {
                    //满减券或无门槛
                    couponStrategy = new FullMinusCoupon();
                    couponContext.setCouponStrategy(couponStrategy);
                }
                try {
                    if (flag) {
                        discountPrice = discountPrice.add(couponContext.execute(shoppingCart.getPrice(), coupon));
                        flag = false;

                    } else {
                        discountPrice = discountPrice.add(shoppingCart.getPrice());
                    }
                } catch (BusinessException e) {
                    throw new BusinessException(e.getMessage());
                }
            }
        }
        List<AddressBook> addressBookList = addressBookService.lambdaQuery().eq(AddressBook::getUserId, userId).list();
        //查询优惠券
        ToPayVo payVo = ToPayVo.builder()
                .goodsList(shoppingCartList)
                .addressBookList(addressBookList)
                .goodsCount(shoppingCartList.size())
                .postFee(BigDecimal.valueOf(0))
                .totalPrice(allPrice)
                .build();
        if (useCoupon) {
            payVo.setDiscountPrice(discountPrice);
        }else {
            payVo.setDiscountPrice(allPrice);
        }
        return payVo;
    }

    /**
     * 生成订单
     *
     * @param order 参数
     * @return 生成的订单
     */
    @Override
    public OrderVo toPay(Order order) throws BusinessException {
        if (order.getAddressBookId() == null) {
            throw new BusinessException("你似乎还没有添加地址");
        }
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get(JwtConst.USER_ID);
        //订单号
        String number = generateNumber(userId);
        //生成订单的时间
        LocalDateTime now = LocalDateTime.now();
        //获取地址簿信息
        AddressBook addressBook = addressBookService.getById(order.getAddressBookId());
        //获取选择的购物车数据
        List<ShoppingCart> shoppingCartList = cartService.lambdaQuery().eq(ShoppingCart::getUserId, userId).eq(ShoppingCart::getSelected, 1).list();
        if (shoppingCartList.isEmpty()) {
            throw new BusinessException("非法操作！");
        }
        BigDecimal discountPrice = new BigDecimal(0);
        boolean flag = true;
        boolean useCoupon = false;
        for (ShoppingCart shoppingCart : shoppingCartList) {
            //购物车里有多少个数据插入多少条数据
            order.setId(null);
            BigDecimal allPrice = new BigDecimal(0);
            allPrice = allPrice.add(shoppingCart.getPrice().multiply(BigDecimal.valueOf(shoppingCart.getCount())));
            if (shoppingCart.getUserCouponId() != null) {
                useCoupon = true;
                UserCoupon userCoupon = userCouponService.getById(shoppingCart.getUserCouponId());
                Coupon coupon = couponService.getById(userCoupon.getCouponId());
                CouponStrategy couponStrategy;
                CouponContext couponContext = new CouponContext();
                //策略模式实现
                //TODO 未考虑券的叠加
                if (coupon.getDiscount() != null) {
                    //折扣券
                    couponStrategy = new DiscountCoupon();
                    couponContext.setCouponStrategy(couponStrategy);
                } else {
                    //满减券或无门槛
                    couponStrategy = new FullMinusCoupon();
                    couponContext.setCouponStrategy(couponStrategy);
                }
                try {
                    if (flag) {
                        discountPrice = discountPrice.add(couponContext.execute(shoppingCart.getPrice(), coupon));
                        flag = false;
                    } else {
                        discountPrice = discountPrice.add(shoppingCart.getPrice());
                    }
                } catch (BusinessException e) {
                    throw new BusinessException(e.getMessage());
                }
            }
            if (useCoupon) {
            order.setDiscountPrice(discountPrice);
            }else {
                order.setDiscountPrice(allPrice);
            }
            order.setGoodsId(shoppingCart.getGoodsId());
            order.setCount(shoppingCart.getCount());
            order.setNumber(number);
            order.setStatus(1);
            order.setUserId(userId);
            order.setOrderTime(now);
            order.setPrice(allPrice);
            order.setPhone(addressBook.getPhone());
            order.setFullAddress(addressBook.getFullAddress());
            order.setConsignee(addressBook.getConsignee());
            try {
                save(order);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        //清空购物车中选中的数据
        cartService.lambdaUpdate().eq(ShoppingCart::getUserId, userId).eq(ShoppingCart::getSelected, 1).remove();
        return BeanUtil.copyProperties(order, OrderVo.class);
    }

    /**
     * 获取订单列表
     *
     * @return 订单列表
     */
    @Override
    public List<OrderVo> getOrderList() {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get(JwtConst.USER_ID);
        List<Order> orders = lambdaQuery().eq(Order::getUserId, userId).list();
        List<OrderVo> orderVoList = BeanUtil.copyToList(orders, OrderVo.class);
        for (OrderVo orderVo : orderVoList) {
            Goods goods = goodsService.lambdaQuery().eq(Goods::getId, orderVo.getGoodsId()).one();
            orderVo.setGoods(goods);
        }
        return orderVoList;
    }

    /**
     * 生成订单
     *
     * @return 订单号
     */
    private String generateNumber(Integer userId) {
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        return snowflake.nextIdStr();
    }

    /**
     * 根据订单编号查询订单信息
     *
     * @param number 订单编号
     * @return 订单信息
     */
    @Override
    public OrderDetailVo getOrderDetail(String number) throws BusinessException {
        List<Order> orderList = lambdaQuery().eq(Order::getNumber, number).list();
        if (orderList.isEmpty()) {
            throw new BusinessException("订单异常，请联系管理员");
        }
        if (!orderList.getFirst().getStatus().equals(1)) {
            throw new BusinessException("订单异常，请联系管理员");
        }
        BigDecimal totalNum = new BigDecimal(0);
        for (Order order : orderList) {
            totalNum = totalNum.add(order.getPrice());
        }
        BigDecimal discountPrice = orderList.getFirst().getDiscountPrice();
        return OrderDetailVo.builder()
                .orderTime(orderList.getFirst().getOrderTime())
                .totalNum(totalNum)
                .discountPrice(discountPrice)
                .build();
    }
}
